<?php


namespace app\shop\service\user;


use app\enterprise\model\Friend;
use app\enterprise\model\Group;
use app\manage\model\Config;
use app\shop\common\consts\Consts;
use app\shop\model\chat\GroupUserModel;
use app\shop\model\order\OrderModel;
use app\shop\model\user\ChatUserModel;
use app\shop\model\user\MessageModel;
use app\shop\model\user\UserModel;
use app\shop\service\BaseService;
use Closure;
use GatewayClient\Gateway;
use think\facade\Db;

class UserService extends BaseService
{
    private static $instance;

    public static $defaultField = 'user_id,realname,realname as displayName,mobile as account,avatar,name_py,email,last_login_ip';

    protected static $gender = ['女', '男', '未知'];

    public static function getInstance()
    {
        if (!self::$instance) {
            self::$instance = new UserModel();
        }
        return self::$instance;
    }


    /**
     * @param $value
     * @return string
     */
    public static function getGender($value): string
    {
        return self::$gender[$value];
    }

    public function __construct()
    {
        $this->model = new UserModel();
    }

    /**
     * 生成登录码
     * @param array $uidArr
     * @param int $startTime 上班时间
     * @param int $endTime 下班时间
     * @param int $code 登录码
     * @param int $type 0手动生成 1自动
     * @return bool
     * @throws \Exception
     */
    public static function generateCode(array $uidArr, int $startTime, int $endTime, int $code = 0, $type = 0): bool
    {
        try {
            foreach ($uidArr as $uid) {
                $user = UserModel::find($uid);
                $user->login_code = $code > 0 ? $code : rand(111111, 999999);
                if ($startTime > 0) {
                    $user->morning_start_work_time = $startTime;
                } else {
                    $workStartTime = $user['morning_start_work_time'] ?: time();
                    $time = date('H:i', $workStartTime);
                    $user->morning_start_work_time = strtotime($time);
                }
                if ($endTime > 0) {
                    $user->afternoon_end_work_time = $endTime;
                } else {
                    $workStartTime = $user['afternoon_end_work_time'] ?: time();
                    $time = date('H:i', $workStartTime);
                    $user->afternoon_end_work_time = strtotime($time);
                }
                if ($type == 1) {
                    $user->last_refresh_code_time = time();
                }
                $user->save();
            }
            return true;
        } catch (\Exception $exception) {
            throw new \Exception($exception->getMessage());
        }
    }

    //查询用户列表
    public static function getUserList($map, $user_id, $field = "")
    {
        $friendList = FriendService::getFriend(['create_user' => $user_id, 'status' => 1]);
        // 如果是社区模式，就只查询自己的好友，如果是企业模式，就查询所有用户
        $userList = array_keys($friendList);
        $list = self::getInstance()->where($map)->where('user_id', 'in', $userList)->field($field)->select();

        $list_chart = chartSort($list, 'realname', false, 'index');
        // 查询未读消息
        $unread = MessageModel::field('from_user,count(msg_id) as unread')
            ->where([['to_user', '=', $user_id], ['is_read', '=', 0], ['is_group', '=', 0]])
            ->group('from_user')
            ->select();
        // 查询最近的联系人
        $map1 = [['to_user', '=', $user_id], ['is_last', '=', 1], ['is_group', '=', 0]];
        $map2 = [['from_user', '=', $user_id], ['is_last', '=', 1], ['is_group', '=', 0]];
        $msgField = 'from_user,to_user,content as lastContent,create_time as lastSendTime,chat_identify,type,del_user';
        $lasMsgList = MessageModel::field($msgField)
            ->whereOr([$map1, $map2])
            ->order('create_time desc')
            ->select();
        try {
            Gateway::$registerAddress = config('gateway.registerAddress');
            $onlineList = Gateway::getAllUidList();
        } catch (\Exception $e) {
            $onlineList = [];
        }
        foreach ($list_chart as $k => $v) {
            // 是否有消息通知或者置顶聊天
            $friend = isset($friendList[$v['user_id']]) ? $friendList[$v['user_id']] : [];
            $list_chart[$k]['id'] = $v['user_id'];
            $list_chart[$k]['displayName'] = ($friend['nickname'] ?? '') ?: $v['realname'];
            $list_chart[$k]['name_py'] = $v['name_py'];
            $list_chart[$k]['avatar'] = avatarUrl($v['avatar'], $v['realname'], $v['user_id'], 120);
            $list_chart[$k]['lastContent'] = '';
            $list_chart[$k]['unread'] = 0;
            $list_chart[$k]['lastSendTime'] = time() * 1000;
            $list_chart[$k]['is_group'] = 0;
            $list_chart[$k]['setting'] = [];
            $list_chart[$k]['is_at'] = 0;
            $list_chart[$k]['last_login_ip'] = $v['last_login_ip'];
            $list_chart[$k]['location'] = $v['last_login_ip'] ? implode(" ", \Ip::find($v['last_login_ip'])) : "未知";
            $is_online = 0;
            if (isset($onlineList[$v['user_id']])) {
                $is_online = 1;
            }
            $list_chart[$k]['is_online'] = $is_online;

            $is_top = 0;
            $is_notice = 1;
            if ($friend) {
                $is_top = $friend['is_top'];
                $is_notice = $friend['is_notice'];
            }
            $list_chart[$k]['is_top'] = $is_top;
            $list_chart[$k]['is_notice'] = $is_notice;
            if ($unread) {
                foreach ($unread as $val) {
                    if ($val['from_user'] == $v['user_id']) {
                        $list_chart[$k]['unread'] = $val['unread'];
                        break;
                    }
                }
            }
            if ($lasMsgList) {
                foreach ($lasMsgList as $val) {
                    if ($val['from_user'] == $v['user_id'] || $val['to_user'] == $v['user_id']) {
                        $content = str_encipher($val['lastContent'], false);
                        // 屏蔽已删除的消息
                        if ($val['del_user']) {
                            $delUser = explode(',', $val['del_user']);
                            if (in_array($user_id, $delUser)) {
                                $content = "";
                            }
                        }
                        $list_chart[$k]['type'] = $val['type'];
                        $list_chart[$k]['lastContent'] = $content;
                        $list_chart[$k]['lastSendTime'] = $val['lastSendTime'] * 1000;

                        break;
                    }
                }
            }
        }
        return $list_chart;
    }

    /**
     * 用户是否在工作时间内
     * @param UserModel $userInfo
     * @return bool
     */
    public static function isInWorkTime(UserModel $userInfo)
    {
        if (!$userInfo) {
            return false;
        }
        $roleId = $userInfo['role_id'];
        if (!in_array($roleId, [Consts::DESIGN_LEADER_ID, Consts::DESIGN_ID])) {
            return true;
        }
        $currentTime = time();
        if ($currentTime < $userInfo['morning_start_work_time'] || $currentTime > $userInfo['afternoon_end_work_time']) {
            return false;
        }
//        if ($currentTime > $userInfo['morning_end_work_time'] && $currentTime < $userInfo['afternoon_start_work_time']) {
//            return false;
//        }
        return true;
    }

    //查询用户列表
    public static function getContactsList($map, $user_id, $field = "")
    {
        if (!$field) {
            $field = self::$defaultField;
        }
        // 好友列表
//        $friendList = Friend::getFriend(['create_user' => $user_id, 'status' => 1]);


        $userInfo = UserModel::find($user_id);
        $userIdArr = FriendService::getFriendIds($userInfo);
        array_push($userIdArr, 1);
        $list = UserModel::where($map)->where('user_id', 'in', $userIdArr)->field($field)->select();

        $list_chart = chartSort($list, 'realname', false, 'index');

        // 查询未读消息
        $unread = Db::name('message')
            ->field('from_user,count(msg_id) as unread')
            ->where([['to_user', '=', $user_id], ['is_read', '=', 0], ['is_group', '=', 0]])
            ->group('from_user')
            ->select();

        // 查询最近的联系人
        $map1 = [['to_user', '=', $user_id], ['is_last', '=', 1], ['is_group', '=', 0]];
        $map2 = [['from_user', '=', $user_id], ['is_last', '=', 1], ['is_group', '=', 0]];
        $msgField = 'from_user,to_user,content as lastContent,create_time as lastSendTime,chat_identify,type,del_user,
        from_user_role_id,to_user_role_id,order_sn';
        $lasMsgList = Db::name('message')
            ->field($msgField)
            ->where('chat_user', 'like', "%{$user_id},%")
            ->order('create_time desc')
            ->select();
        try {
            Gateway::$registerAddress = config('gateway.registerAddress');
            $onlineList = Gateway::getAllUidList();
        } catch (\Exception $e) {
            $onlineList = [];
        }
        foreach ($list_chart as $k => $v) {
            $list_chart[$k]['id'] = $v['user_id'];
            $list_chart[$k]['displayName'] = $v['realname'];
            $list_chart[$k]['name_py'] = $v['name_py'];
            $list_chart[$k]['lastContent'] = '';
            $list_chart[$k]['unread'] = 0;
            $list_chart[$k]['lastSendTime'] = time() * 1000;
            $list_chart[$k]['is_group'] = 0;
            $list_chart[$k]['setting'] = [];
            $list_chart[$k]['is_at'] = 0;
            $list_chart[$k]['last_login_ip'] = $v['last_login_ip'];
            $list_chart[$k]['location'] = $v['last_login_ip'] ? implode(" ", \Ip::find($v['last_login_ip'])) : "未知";
            $is_online = 0;
            if (isset($onlineList[$v['user_id']])) {
                $is_online = 1;
            }
            $list_chart[$k]['is_online'] = $is_online;
            $list_chart[$k]['is_top'] = 0;
            $list_chart[$k]['is_notice'] = 1;
            if ($unread) {
                foreach ($unread as $val) {
                    if ($val['from_user'] == $v['user_id']) {
                        $list_chart[$k]['unread'] = $val['unread'];
                        break;
                    }
                }
            }

            if ($lasMsgList) {
                foreach ($lasMsgList as $val) {
                    if ($val['from_user'] == $v['user_id'] || $val['to_user'] == $v['user_id']) {
                        // 如果是设计师和客户的聊天 订单结束聊天结束
                        if (self::chatIsCustomerAndDesign($val['from_user_role_id'], $val['to_user_role_id'])) {
                            $orderInfo = OrderModel::where('order_sn', $val['order_sn'])->find();
                            if ($orderInfo) {
                                if ($orderInfo['order_status'] != 1 || $orderInfo['design_id'] != $v['user_id'])
                                    $list_chart[$k]['lastContent'] = '';
                                break;
                            }
                        }
                        $content = str_encipher($val['lastContent'], false);
                        // 屏蔽已删除的消息
                        if ($val['del_user']) {
                            $delUser = explode(',', $val['del_user']);
                            if (in_array($user_id, $delUser)) {
                                $content = "";
                            }
                        }
                        $list_chart[$k]['type'] = $val['type'];
                        $list_chart[$k]['lastContent'] = $content;
                        $list_chart[$k]['lastSendTime'] = $val['lastSendTime'] * 1000;

                        break;
                    }
                }

            }
        }
        return $list_chart;
    }

    /**
     * 是否客户和设计师聊天
     * @param $fromRoleId
     * @param $toRoleId
     * @return bool
     */
    public static function chatIsCustomerAndDesign($fromRoleId, $toRoleId)
    {
        if (in_array($fromRoleId, [Consts::DESIGN_LEADER_ID, Consts::DESIGN_ID]) && $toRoleId == Consts::CUSTOMER_ID) {
            return true;
        }
        if (in_array($toRoleId, [Consts::DESIGN_LEADER_ID, Consts::DESIGN_ID]) && $fromRoleId == Consts::CUSTOMER_ID) {
            return true;
        }
        return false;
    }

    /**
     * 获取用户在线状态
     * @param $userId
     * @param string $userInfo
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function getUserOnlineStatus($userId, $userInfo = '')
    {
        if (!$userInfo) {
            $userInfo = self::getInstance()::find($userId);
        }
        $loginStatus = $userInfo['login_status'];
        try {
            $onlineList = Gateway::getAllUidList();
            $online = isset($onlineList[$userId]) ? 1 : 0;
            return ['online' => $online, 'login_status' => $loginStatus];
        } catch (\Exception $exception) {
            return ['online' => 0, 'login_status' => $loginStatus];
        }

    }

    /**
     * 用户所有websocket断开链接
     * @param $userId
     * @return bool
     * @throws \Exception
     */
    public static function userOffline($userId)
    {
        try {
            Gateway::$registerAddress = config('gateway.registerAddress');
            $clientIdArr = Gateway::getClientIdByUid($userId);
            if (!$clientIdArr) {
                return true;
            }
            foreach ($clientIdArr as $clientId) {
                Gateway::closeClient($clientId);
            }
            $data = [
                'type' => 'isOnline',
                'time' => time(),
                'data' => ['id' => $userId, 'is_online' => 0, 'login_status' => 0, 'route' => 'userOffline']
            ];
            Gateway::sendToAll(json_encode($data));
            return true;
        } catch (\Exception $exception) {
            throw new \Exception($exception->getMessage());
        }
    }
}